电机控制脉宽调制器 (MCPWM)

您所在的位置:网站首页 esp32 输出 电机控制脉宽调制器 (MCPWM)

电机控制脉宽调制器 (MCPWM)

2023-06-23 09:17| 来源: 网络整理| 查看: 265

功能概述

下文将分节概述 MCPWM 的功能:

资源配置及初始化 - 介绍各类 MCPWM 模块的分配,如定时器、操作器、比较器、生成器等。随后介绍的 IO 设置和控制功能也将围绕这些模块进行。

定时器操作和事件 - 介绍 MCPWM 定时器支持的控制功能和事件回调。

比较器操作和事件 - 介绍 MCPWM 比较器支持的控制功能和事件回调。

生成器对事件执行的操作 - 介绍如何针对 MCPWM 定时器和比较器生成的特定事件,设置 MCPWM 生成器的相应执行操作。

经典 PWM 波形的生成器配置 - 介绍一些经典 PWM 波形的生成器配置。

死区 - 介绍如何设置 MCPWM 生成器的死区时间。

经典 PWM 波形的死区配置 - 介绍一些经典 PWM 波形的死区配置。

载波调制 - 介绍如何在最终输出的 PWM 波形上调制高频载波。

故障检测和制动控制 - 介绍如何为 MCPWM 操作器配置特定故障事件下的制动操作。

生成器强制操作 - 介绍如何强制异步控制生成器的输出水平。

同步模块 - 介绍如何同步 MCPWM 定时器,并确保生成的最终输出 PWM 信号具有固定的相位差。

捕获模块 - 介绍如何使用 MCPWM 捕获模块测量信号脉宽。

电源管理 - 介绍不同的时钟源对功耗的影响。

IRAM 安全 - 介绍如何协调 RMT 中断与禁用缓存。

线程安全 - 列出了由驱动程序认证为线程安全的 API。

Kconfig 选项 - 列出了针对驱动的数个 Kconfig 支持选项。

资源配置及初始化

如上图所示,MCPWM 外设由数个子模块组成。本节将介绍各个子模块的资源配置方式。

MCPWM 定时器

调用 mcpwm_new_timer() 函数,以配置结构体 mcpwm_timer_config_t 为参数,分配一个 MCPWM 定时器为对象。结构体定义为:

mcpwm_timer_config_t::group_id 指定 MCPWM 组 ID,范围为 [0, SOC_MCPWM_GROUPS - 1]。需注意,位于不同组的定时器彼此独立。

mcpwm_timer_config_t::clk_src 设置定时器的时钟源。

mcpwm_timer_config_t::resolution_hz 设置定时器的预期分辨率。内部驱动将根据时钟源和分辨率设置合适的分频器。

mcpwm_timer_config_t::count_mode 设置定时器的计数模式。

mcpwm_timer_config_t::period_ticks 设置定时器的周期,以 Tick 为单位(通过 mcpwm_timer_config_t::resolution_hz 设置 Tick 分辨率)。

mcpwm_timer_config_t::update_period_on_empty 设置当定时器计数为零时是否更新周期值。

mcpwm_timer_config_t::update_period_on_sync 设置当定时器接收同步信号时是否更新周期值。

分配成功后,mcpwm_new_timer() 将返回一个指向已分配定时器的指针。否则,函数将返回错误代码。具体来说,当 MCPWM 组中没有空闲定时器时,将返回 ESP_ERR_NOT_FOUND 错误。1

反之,调用 mcpwm_del_timer() 函数将释放已分配的定时器。

MCPWM 操作器

调用 mcpwm_new_operator()() 函数,以配置结构体 mcpwm_operator_config_t 为参数,分配一个 MCPWM 操作器为对象。结构体定义为:

mcpwm_operator_config_t::group_id 指定 MCPWM 组 ID,范围为 [0, SOC_MCPWM_GROUPS - 1]。需注意,位于不同组的操作器彼此独立。

mcpwm_operator_config_t::update_gen_action_on_tez 设置是否在定时器计数为零时更新生成器操作。此处及下文提到的定时器指通过 mcpwm_operator_connect_timer() 连接到操作器的定时器。

mcpwm_operator_config_t::update_gen_action_on_tep 设置当定时器计数达到峰值时是否更新生成器操作。

mcpwm_operator_config_t::update_gen_action_on_sync 设置当定时器接收同步信号时是否更新生成器操作。

mcpwm_operator_config_t::update_dead_time_on_tez 设置当定时器计数为零时是否更新死区时间。

mcpwm_operator_config_t::update_dead_time_on_tep 设置当定时器计数达到峰值时是否更新死区时间。

mcpwm_operator_config_t::update_dead_time_on_sync 设置当定时器接收同步信号时是否更新死区时间。

分配成功后,mcpwm_new_operator()() 将返回一个指向已分配操作器的指针。否则,函数将返回错误代码。具体来说,当 MCPWM 组中没有空闲操作器时,将返回 ESP_ERR_NOT_FOUND 错误。1

反之,调用 mcpwm_del_operator()() 函数将释放已分配的操作器。

MCPWM 比较器

调用 mcpwm_new_comparator() 函数,以一个 MCPWM 操作器句柄和配置结构体 mcpwm_comparator_config_t 为参数,分配一个 MCPWM 比较器为对象。操作器句柄由 mcpwm_new_operator()() 生成,结构体定义为:

mcpwm_comparator_config_t::update_cmp_on_tez 设置当定时器计数为零时是否更新比较阈值。

mcpwm_comparator_config_t::update_cmp_on_tep 设置当定时器计数达到峰值时是否更新比较阈值。

mcpwm_comparator_config_t::update_cmp_on_sync 设置当定时器接收同步信号时是否更新比较阈值。

分配成功后,mcpwm_new_comparator() 将返回一个指向已分配比较器的指针。否则,函数将返回错误代码。具体来说,当 MCPWM 操作器中没有空闲比较器时,将返回 ESP_ERR_NOT_FOUND 错误。1

反之,调用 mcpwm_del_comparator() 函数将释放已分配的比较器。

MCPWM 生成器

调用 mcpwm_new_generator() 函数,以一个 MCPWM 操作器句柄和配置结构体 mcpwm_generator_config_t 为参数,分配一个 MCPWM 生成器为对象。操作器句柄由 mcpwm_new_operator()() 生成,结构体定义为:

mcpwm_generator_config_t::gen_gpio_num 设置生成器使用的 GPIO 编号。

mcpwm_generator_config_t::invert_pwm 设置是否反相 PWM 信号。

mcpwm_generator_config_t::io_loop_back 设置是否启用回环模式。该模式仅用于调试,使用 GPIO 交换矩阵外设同时启用 GPIO 输入和输出。

分配成功后,mcpwm_new_generator() 将返回一个指向已分配生成器的指针。否则,函数将返回错误代码。具体来说,当 MCPWM 操作器中没有空闲生成器时,将返回 ESP_ERR_NOT_FOUND 错误。1

反之,调用 mcpwm_del_generator() 函数将释放已分配的生成器。

MCPWM 故障

MCPWM 故障分为两种类型:来自 GPIO 的故障信号和软件故障。

调用 mcpwm_new_gpio_fault() 函数,以配置结构体 mcpwm_gpio_fault_config_t 为参数,分配一个 GPIO 故障为对象。结构体定义为:

mcpwm_gpio_fault_config_t::group_id 设置 MCPWM 组 ID,范围为 [0, SOC_MCPWM_GROUPS - 1]。需注意,位于不同组的 GPIO 故障彼此独立,也就是说,1 组的操作器无法检测到 0 组的 GPIO 故障。

mcpwm_gpio_fault_config_t::gpio_num 设置故障所使用的 GPIO 编号。

mcpwm_gpio_fault_config_t::active_level 设置故障信号的有效电平。

mcpwm_gpio_fault_config_t::pull_up 和 mcpwm_gpio_fault_config_t::pull_down 设置是否在内部拉高和/或拉低 GPIO。

mcpwm_gpio_fault_config_t::io_loop_back 设置是否启用回环模式。该模式仅用于调试,使用 GPIO 交换矩阵外设同时启用 GPIO 输入和输出。

分配成功后,mcpwm_new_gpio_fault() 将返回一个指向已分配故障的指针。否则,函数将返回错误代码。具体来说,当指定 MCPWM 组中没有空闲 GPIO 故障时,将返回 ESP_ERR_NOT_FOUND 错误。1

调用函数 mcpwm_soft_fault_activate() 使一个软件故障对象触发故障,无需等待来自 GPIO 的真实故障信号。调用 mcpwm_new_soft_fault() 函数,以配置结构体 mcpwm_soft_fault_config_t 为参数,分配一个软件故障为对象。该结构体暂时保留,供后续使用。

分配成功后,mcpwm_new_soft_fault() 将返回一个指向已分配故障的指针。否则,函数将返回错误代码。具体来说,当内存不足以支持该故障对象时,将返回 ESP_ERR_NO_MEM 错误。虽然软件故障和 GPIO 故障是不同类型的故障,但返回的故障句柄为同一类型。

反之,调用 mcpwm_del_fault() 函数将释放已分配的故障。此函数同时适用于软件故障和 GPIO 故障。

MCPWM 同步源

同步源用于同步 MCPWM 定时器和 MCPWM 捕获定时器,分为三种类型:来自 GPIO 的同步源、软件生成的同步源和 MCPWM 定时器事件生成的同步源。

调用 mcpwm_new_gpio_sync_src() 函数,以配置结构体 mcpwm_gpio_sync_src_config_t 为参数,分配一个 GPIO 同步源。结构体定义为:

mcpwm_gpio_sync_src_config_t::group_id 指定 MCPWM 组 ID,范围为 [0, SOC_MCPWM_GROUPS - 1]。需注意,位于不同组的 GPIO 同步源彼此独立,也就是说,1 组的定时器无法检测到 0 组的 GPIO 同步源。

mcpwm_gpio_sync_src_config_t::gpio_num 设置同步源使用的 GPIO 编号。

mcpwm_gpio_sync_src_config_t::active_neg 设置同步信号在下降沿是否有效。

mcpwm_gpio_sync_src_config_t::pull_up 和 mcpwm_gpio_sync_src_config_t::pull_down 设置是否在内部拉高和/或拉低 GPIO。

mcpwm_gpio_sync_src_config_t::io_loop_back 设置是否启用回环模式。该模式仅用于调试,使用 GPIO 交换矩阵外设同时启用 GPIO 输入和输出。

分配成功后,mcpwm_new_gpio_sync_src() 将返回一个指向已分配同步源的指针。否则,函数将返回错误代码。具体来说,当 MCPWM 组中没有空闲 GPIO 时钟源时,将返回 ESP_ERR_NOT_FOUND 错误。1

调用 mcpwm_new_timer_sync_src() 函数,以配置结构体 mcpwm_timer_sync_src_config_t 为参数,分配一个定时器事件同步源。结构体定义为:

mcpwm_timer_sync_src_config_t::timer_event 指定产生同步信号的定时器事件。

mcpwm_timer_sync_src_config_t::propagate_input_sync 是否广播输入同步信号(即将输入同步信号传输到其同步输出)。

分配成功后,mcpwm_new_timer_sync_src() 将返回一个指向已分配同步源的指针。否则,函数将返回错误代码。具体来说,若是分配的同步源此前已分配给了同一个定时器,将返回 ESP_ERR_INVALID_STATE 错误。

也可以调用 mcpwm_new_soft_sync_src() 函数,以配置结构体 mcpwm_soft_sync_config_t 为参数,分配一个软件同步源。该结构体暂时保留,供后续使用。

分配成功后,mcpwm_new_soft_sync_src() 将返回一个指向已分配同步源的指针。否则,函数将返回错误代码。具体来说,当内存不足以支持分配的同步源时,将返回 ESP_ERR_NO_MEM 错误。需注意,为确保软件同步源能够正常工作,应预先调用 mcpwm_soft_sync_activate()。

相反,调用 mcpwm_del_sync_src() 函数将释放分配的同步源对象。此函数适用于所有类型的同步源。

MCPWM 捕获定时器和通道

MCPWM 组有一个专用定时器,用于捕获特定事件发生时的时间戳。捕获定时器连接了数个独立通道,每个通道都分配了各自的 GPIO。

调用 mcpwm_new_capture_timer() 函数,以配置结构体 mcpwm_capture_timer_config_t 为参数,分配一个捕获定时器。结构体定义为:

mcpwm_capture_timer_config_t::group_id 设置 MCPWM 组 ID,范围为 [0, SOC_MCPWM_GROUPS - 1]。

mcpwm_capture_timer_config_t::clk_src 设置捕获定时器的时钟源。

分配成功后,mcpwm_new_capture_timer() 将返回一个指向已分配捕获定时器的指针。否则,函数将返回错误代码。具体来说,当 MCPWM 组中没有空闲捕获定时器时,将返回 ESP_ERR_NOT_FOUND 错误。1

接下来,可以调用 mcpwm_new_capture_channel() 函数,以一个捕获定时器句柄和配置结构体 mcpwm_capture_channel_config_t 为参数,分配一个捕获通道。结构体定义为:

mcpwm_capture_channel_config_t::gpio_num 设置捕获通道使用的 GPIO 编号。

mcpwm_capture_channel_config_t::prescale 设置输入信号的预分频器。

mcpwm_capture_channel_config_t::pos_edge 和 mcpwm_capture_channel_config_t::neg_edge 设置是否在输入信号的上升沿和/或下降沿捕获时间戳。

mcpwm_capture_channel_config_t::pull_up 和 mcpwm_capture_channel_config_t::pull_down 设置是否在内部拉高和/或拉低 GPIO。

mcpwm_capture_channel_config_t::invert_cap_signal 设置是否取反捕获信号。

mcpwm_capture_channel_config_t::io_loop_back 设置是否启用回环模式。该模式仅用于调试,使用 GPIO 交换矩阵外设同时启用 GPIO 输入和输出。

分配成功后,mcpwm_new_capture_channel() 将返回一个指向已分配捕获通道的指针。否则,函数将返回错误代码。具体来说,当捕获定时器中没有空闲捕获通道时,将返回 ESP_ERR_NOT_FOUND 错误。

反之,调用 mcpwm_del_capture_channel() 和 mcpwm_del_capture_timer() 将释放已分配的捕获通道和定时器。

定时器操作和事件 注册定时器事件回调

MCPWM 定时器运行时会生成不同的事件。若有函数需在特定事件发生时调用,则应预先调用 mcpwm_timer_register_event_callbacks(),将所需函数挂载至中断服务程序 (ISR) 中。驱动中定时器回调函数原型声明为 mcpwm_timer_event_cb_t,其所支持的事件回调类型则列在 mcpwm_timer_event_callbacks_t 中:

mcpwm_timer_event_callbacks_t::on_full 设置定时器计数达到峰值时的回调函数。

mcpwm_timer_event_callbacks_t::on_empty 设置定时器计数为零时的回调函数。

mcpwm_timer_event_callbacks_t::on_stop 设置定时器停止时的回调函数。

由于上述回调函数是在 ISR 中调用的,因此,这些函数 不应 涉及 block 操作。可以检查调用 API 的后缀,确保在函数中只调用了后缀为 ISR 的 FreeRTOS API。

函数 mcpwm_timer_register_event_callbacks() 中的 user_data 参数用于保存用户上下文,将直接传递至各个回调函数。

此函数会在不启用 MCPWM 定时器的情况下延迟安装其中断服务。因此,需在调用 mcpwm_timer_enable() 函数前调用该函数,否则将返回 ESP_ERR_INVALID_STATE 错误。更多信息请参见 启用和禁用定时器。

启用和禁用定时器

在对定时器进行 IO 控制前,需要预先调用 mcpwm_timer_enable() 函数启用定时器。这个函数将:

将定时器的状态从 init 切换到 enable。

若中断服务此前已通过 mcpwm_timer_register_event_callbacks() 函数延迟安装,则启用中断服务。

若选择了特定时钟源(例如 PLL_160M 时钟),则获取相应的电源管理锁。更多信息请参见 电源管理。

反之,调用 mcpwm_timer_disable() 会将定时器切换回 init 状态、禁用中断服务并释放电源管理锁。

启动和停止定时器

通过基本的 IO 控制,即可启动和停止定时器。使用不同的 mcpwm_timer_start_stop_cmd_t 命令调用 mcpwm_timer_start_stop() 便可立即启动定时器,或在发生特定事件时停止定时器。此外,还可以通过配置,让定时器仅计数一轮。也就是说,在计数达到峰值或零后,定时器自行停止。

连接定时器和操作器

调用 mcpwm_operator_connect_timer() 函数,连接分配的 MCPWM 定时器和 MCPWM 操作器。连接后,操作器即可将定时器作为时基,生成所需的 PWM 波形。需注意,MCPWM 定时器和操作器必须位于同一个组中。否则,将返回 ESP_ERR_INVALID_ARG 错误。

比较器操作和事件 注册比较器事件回调

MCPWM 比较器可以在定时器计数器等于比较值时发送通知。若有函数需在比较事件发生时调用,则应预先调用 mcpwm_comparator_register_event_callbacks(),将所需函数挂载至中断服务程序 (ISR) 中。驱动中比较器回调函数原型声明为 mcpwm_compare_event_cb_t,其所支持的事件回调类型则列在 mcpwm_comparator_event_callbacks_t 中:

mcpwm_comparator_event_callbacks_t::on_reach 设置当定时器计数器等于比较值时的比较器回调函数。

回调函数会提供类型为 mcpwm_compare_event_data_t 的事件特定数据。由于上述回调函数是在 ISR 中调用的,因此,这些函数 不应 涉及 block 操作。可以检查调用 API 的后缀,确保在函数中只调用了后缀为 ISR 的 FreeRTOS API。

函数 mcpwm_comparator_register_event_callbacks() 中的 user_data 参数用于保存用户上下文,将直接传递至各个回调函数。

此函数会延迟安装 MCPWM 比较器的中断服务。中断服务只能通过 mcpwm_del_comparator 移除。

设置比较值

运行 MCPWM 比较器时,可以调用 mcpwm_comparator_set_compare_value() 设置比较值。需注意以下几点:

重新设置的比较值可能不会立即生效。比较值的更新时间通过 mcpwm_comparator_config_t::update_cmp_on_tez 或 mcpwm_comparator_config_t::update_cmp_on_tep 或 mcpwm_comparator_config_t::update_cmp_on_sync 配置。

请确保已经预先调用 mcpwm_operator_connect_timer() 将操作器连接至 MCPWM 定时器。否则,将返回 ESP_ERR_INVALID_STATE 错误。

比较值不应超过定时器的计数峰值。否则,将无法触发比较事件。

生成器对事件执行的操作 设置生成器对定时器事件执行的操作

调用 mcpwm_generator_set_actions_on_timer_event() 并辅以若干操作配置,可以针对不同的定时器事件,为生成器设置不同的操作。操作配置定义在 mcpwm_gen_timer_event_action_t 中:

mcpwm_gen_timer_event_action_t::direction 指定定时器计数方向,可以调用 mcpwm_timer_direction_t 查看支持的方向。

mcpwm_gen_timer_event_action_t::event 指定定时器事件,可以调用 mcpwm_timer_event_t 查看支持的定时器事件。

mcpwm_gen_timer_event_action_t::action 指定随即进行的生成器操作,可以调用 mcpwm_generator_action_t 查看支持的操作。

可借助辅助宏 MCPWM_GEN_TIMER_EVENT_ACTION 构建定时器事件操作条目。

需注意,mcpwm_generator_set_actions_on_timer_event() 的参数列表 必须 以 MCPWM_GEN_TIMER_EVENT_ACTION_END 结束。

也可以调用 mcpwm_generator_set_action_on_timer_event() 逐一设置定时器操作,无需涉及变量参数。

设置生成器对比较器事件执行的操作

调用 mcpwm_generator_set_actions_on_compare_event() 并辅以若干操作配置,可以针对不同的比较器事件,为生成器设置不同的操作。操作配置定义在 mcpwm_gen_compare_event_action_t 中:

mcpwm_gen_compare_event_action_t::direction 指定定时器计数方向,可以调用 mcpwm_timer_direction_t 查看支持的方向。

mcpwm_gen_compare_event_action_t::comparator 指定比较器句柄。有关分配比较器的方法,请参见 MCPWM 比较器。

mcpwm_gen_compare_event_action_t::action 指定随即进行的生成器操作,可以调用 mcpwm_generator_action_t 查看支持的操作。

可借助辅助宏 MCPWM_GEN_COMPARE_EVENT_ACTION 构建比较事件操作条目。

需注意,mcpwm_generator_set_actions_on_compare_event() 的参数列表 必须 以 MCPWM_GEN_COMPARE_EVENT_ACTION_END 结束。

也可以调用 mcpwm_generator_set_action_on_compare_event() 逐一设置定时器操作,无需涉及变量参数。

经典 PWM 波形的生成器配置

本节提供了一些生成器支持生成的经典 PWM 波形,同时提供用于生成这些波形的代码片段。总的来说:

生成波形为 对称波形 还是 不对称波形 取决于 MCPWM 定时器的计数模式。

波形对的 激活电平 取决于占空比较小的 PWM 波形的电平。

PWM 波形的周期取决于定时器的周期和计数模式。

PWM 波形的占空比取决于生成器的各种操作配置组合。

单边不对称波形 - 高电平 static void gen_action_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb, mcpwm_cmpr_handle_t cmpa, mcpwm_cmpr_handle_t cmpb) { ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(gena, MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH))); ESP_ERROR_CHECK(mcpwm_generator_set_action_on_compare_event(gena, MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpa, MCPWM_GEN_ACTION_LOW))); ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(genb, MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH))); ESP_ERROR_CHECK(mcpwm_generator_set_action_on_compare_event(genb, MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpb, MCPWM_GEN_ACTION_LOW))); } 单边不对称波形 - 低电平 static void gen_action_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb, mcpwm_cmpr_handle_t cmpa, mcpwm_cmpr_handle_t cmpb) { ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(gena, MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_FULL, MCPWM_GEN_ACTION_LOW))); ESP_ERROR_CHECK(mcpwm_generator_set_action_on_compare_event(gena, MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpa, MCPWM_GEN_ACTION_HIGH))); ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(genb, MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_FULL, MCPWM_GEN_ACTION_LOW))); ESP_ERROR_CHECK(mcpwm_generator_set_action_on_compare_event(genb, MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpb, MCPWM_GEN_ACTION_HIGH))); } 脉冲位置不对称波形 static void gen_action_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb, mcpwm_cmpr_handle_t cmpa, mcpwm_cmpr_handle_t cmpb) { ESP_ERROR_CHECK(mcpwm_generator_set_actions_on_compare_event(gena, MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpa, MCPWM_GEN_ACTION_HIGH), MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpb, MCPWM_GEN_ACTION_LOW), MCPWM_GEN_COMPARE_EVENT_ACTION_END())); ESP_ERROR_CHECK(mcpwm_generator_set_actions_on_timer_event(genb, MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_TOGGLE), MCPWM_GEN_TIMER_EVENT_ACTION_END())); } 双沿不对称波形 - 低电平有效 static void gen_action_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb, mcpwm_cmpr_handle_t cmpa, mcpwm_cmpr_handle_t cmpb) { ESP_ERROR_CHECK(mcpwm_generator_set_actions_on_compare_event(gena, MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpa, MCPWM_GEN_ACTION_HIGH), MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_DOWN, cmpb, MCPWM_GEN_ACTION_LOW), MCPWM_GEN_COMPARE_EVENT_ACTION_END())); ESP_ERROR_CHECK(mcpwm_generator_set_actions_on_timer_event(genb, MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_LOW), MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_FULL, MCPWM_GEN_ACTION_HIGH), MCPWM_GEN_TIMER_EVENT_ACTION_END())); } 双沿对称波形 - 低电平有效 static void gen_action_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb, mcpwm_cmpr_handle_t cmpa, mcpwm_cmpr_handle_t cmpb) { ESP_ERROR_CHECK(mcpwm_generator_set_actions_on_compare_event(gena, MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpa, MCPWM_GEN_ACTION_HIGH), MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_DOWN, cmpa, MCPWM_GEN_ACTION_LOW), MCPWM_GEN_COMPARE_EVENT_ACTION_END())); ESP_ERROR_CHECK(mcpwm_generator_set_actions_on_compare_event(genb, MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpb, MCPWM_GEN_ACTION_HIGH), MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_DOWN, cmpb, MCPWM_GEN_ACTION_LOW), MCPWM_GEN_COMPARE_EVENT_ACTION_END())); } 双沿对称波形 - 互补 static void gen_action_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb, mcpwm_cmpr_handle_t cmpa, mcpwm_cmpr_handle_t cmpb) { ESP_ERROR_CHECK(mcpwm_generator_set_actions_on_compare_event(gena, MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpa, MCPWM_GEN_ACTION_HIGH), MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_DOWN, cmpa, MCPWM_GEN_ACTION_LOW), MCPWM_GEN_COMPARE_EVENT_ACTION_END())); ESP_ERROR_CHECK(mcpwm_generator_set_actions_on_compare_event(genb, MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpb, MCPWM_GEN_ACTION_LOW), MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_DOWN, cmpb, MCPWM_GEN_ACTION_HIGH), MCPWM_GEN_COMPARE_EVENT_ACTION_END())); } 死区

在电力电子学中,常常会用到整流器和逆变器,这就涉及到了整流桥和逆变桥的应用。每个桥臂配有两个功率电子器件,例如 MOSFET、IGBT 等。同一桥臂上的两个 MOSFET 不能同时导通,否则会造成短路。实际应用中,在 PWM 波形显示 MOSFET 开关已关闭后,仍需要一段时间窗口才能完全关闭 MOSFET。因此,需要设置 生成器对事件执行的操作,在已生成的 PWM 波形上添加额外延迟。

死区驱动器的工作方式与 装饰器 类似。在 mcpwm_generator_set_dead_time() 函数的参数中,驱动接收主要生成器句柄 (in_generator),并在应用死区后返回一个新的生成器 (out_generator)。需注意,如果 out_generator 和 in_generator 相同,这表示 PWM 波形中的时间延迟是以“就地”的方式添加的。反之,如果 out_generator 和 in_generator 不同,则代表在原 in_generator 的基础上派生出了一个新的 PWM 波形。

结构体 mcpwm_dead_time_config_t 中列出了死区相关的具体配置:

mcpwm_dead_time_config_t::posedge_delay_ticks 和 mcpwm_dead_time_config_t::negedge_delay_ticks 设置 PWM 波形上升沿和下降沿上的延迟时间,以 Tick 为单位。若将这两个参数设置为 0,则代表绕过死区模块。死区的 Tick 分辨率与通过 mcpwm_operator_connect_timer() 连接操作器的定时器相同。

mcpwm_dead_time_config_t::invert_output 设置是否在应用死区后取反信号,以控制延迟边沿的极性。

警告

由于硬件限制,同一种 delay 模块(posedge delay 或者 negedge delay)不能同时被应用在不同的 MCPWM 生成器中。例如,以下配置是无效的:

mcpwm_dead_time_config_t dt_config = { .posedge_delay_ticks = 10, }; // 给 generator A 叠加上升沿 delay mcpwm_generator_set_dead_time(mcpwm_gen_a, mcpwm_gen_a, &dt_config); // NOTE: 下面的操作是无效的,不能将同一种 delay 应用于不同的 generator 上 mcpwm_generator_set_dead_time(mcpwm_gen_b, mcpwm_gen_b, &dt_config);

然而,您可以为生成器 A 设置 posedge delay,为生成器 B 设置 negedge delay。另外,您也可以为生成器 A 同时设置 posedge delay 和 negedge delay,而让生成器 B 绕过死区模块。

备注

也可以通过设置 生成器对事件执行的操作 来生成所需的死区,通过不同的比较器来控制边沿位置。但是,如果需要使用经典的基于边沿延迟并附带极性控制的死区,则应使用死区子模块。

经典 PWM 波形的死区配置

本节提供了一些死区子模块支持生成的经典 PWM 波形,同时在图片下方提供用于生成这些波形的代码片段。

高电平有效互补 static void gen_action_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb, mcpwm_cmpr_handle_t cmpa, mcpwm_cmpr_handle_t cmpb) { ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(gena, MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH))); ESP_ERROR_CHECK(mcpwm_generator_set_action_on_compare_event(gena, MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpa, MCPWM_GEN_ACTION_LOW))); } static void dead_time_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb) { mcpwm_dead_time_config_t dead_time_config = { .posedge_delay_ticks = 50, .negedge_delay_ticks = 0 }; ESP_ERROR_CHECK(mcpwm_generator_set_dead_time(gena, gena, &dead_time_config)); dead_time_config.posedge_delay_ticks = 0; dead_time_config.negedge_delay_ticks = 100; dead_time_config.flags.invert_output = true; ESP_ERROR_CHECK(mcpwm_generator_set_dead_time(gena, genb, &dead_time_config)); } 低电平有效互补 static void gen_action_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb, mcpwm_cmpr_handle_t cmpa, mcpwm_cmpr_handle_t cmpb) { ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(gena, MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH))); ESP_ERROR_CHECK(mcpwm_generator_set_action_on_compare_event(gena, MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpa, MCPWM_GEN_ACTION_LOW))); } static void dead_time_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb) { mcpwm_dead_time_config_t dead_time_config = { .posedge_delay_ticks = 50, .negedge_delay_ticks = 0, .flags.invert_output = true }; ESP_ERROR_CHECK(mcpwm_generator_set_dead_time(gena, gena, &dead_time_config)); dead_time_config.posedge_delay_ticks = 0; dead_time_config.negedge_delay_ticks = 100; dead_time_config.flags.invert_output = false; ESP_ERROR_CHECK(mcpwm_generator_set_dead_time(gena, genb, &dead_time_config)); } 高电平有效 static void gen_action_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb, mcpwm_cmpr_handle_t cmpa, mcpwm_cmpr_handle_t cmpb) { ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(gena, MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH))); ESP_ERROR_CHECK(mcpwm_generator_set_action_on_compare_event(gena, MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpa, MCPWM_GEN_ACTION_LOW))); } static void dead_time_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb) { mcpwm_dead_time_config_t dead_time_config = { .posedge_delay_ticks = 50, .negedge_delay_ticks = 0, }; ESP_ERROR_CHECK(mcpwm_generator_set_dead_time(gena, gena, &dead_time_config)); dead_time_config.posedge_delay_ticks = 0; dead_time_config.negedge_delay_ticks = 100; ESP_ERROR_CHECK(mcpwm_generator_set_dead_time(gena, genb, &dead_time_config)); } 低电平有效 static void gen_action_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb, mcpwm_cmpr_handle_t cmpa, mcpwm_cmpr_handle_t cmpb) { ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(gena, MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH))); ESP_ERROR_CHECK(mcpwm_generator_set_action_on_compare_event(gena, MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpa, MCPWM_GEN_ACTION_LOW))); } static void dead_time_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb) { mcpwm_dead_time_config_t dead_time_config = { .posedge_delay_ticks = 50, .negedge_delay_ticks = 0, .flags.invert_output = true }; ESP_ERROR_CHECK(mcpwm_generator_set_dead_time(gena, gena, &dead_time_config)); dead_time_config.posedge_delay_ticks = 0; dead_time_config.negedge_delay_ticks = 100; ESP_ERROR_CHECK(mcpwm_generator_set_dead_time(gena, genb, &dead_time_config)); } PWMA 上升沿延迟,绕过 PWMB 死区 static void gen_action_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb, mcpwm_cmpr_handle_t cmpa, mcpwm_cmpr_handle_t cmpb) { ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(gena, MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH))); ESP_ERROR_CHECK(mcpwm_generator_set_action_on_compare_event(gena, MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpa, MCPWM_GEN_ACTION_LOW))); ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(genb, MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH))); ESP_ERROR_CHECK(mcpwm_generator_set_action_on_compare_event(genb, MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpb, MCPWM_GEN_ACTION_LOW))); } static void dead_time_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb) { mcpwm_dead_time_config_t dead_time_config = { .posedge_delay_ticks = 50, .negedge_delay_ticks = 0, }; // apply deadtime to generator_a ESP_ERROR_CHECK(mcpwm_generator_set_dead_time(gena, gena, &dead_time_config)); // bypass deadtime module for generator_b dead_time_config.posedge_delay_ticks = 0; ESP_ERROR_CHECK(mcpwm_generator_set_dead_time(genb, genb, &dead_time_config)); } PWMB 下降沿延迟,绕过 PWMA 死区 static void gen_action_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb, mcpwm_cmpr_handle_t cmpa, mcpwm_cmpr_handle_t cmpb) { ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(gena, MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH))); ESP_ERROR_CHECK(mcpwm_generator_set_action_on_compare_event(gena, MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpa, MCPWM_GEN_ACTION_LOW))); ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(genb, MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH))); ESP_ERROR_CHECK(mcpwm_generator_set_action_on_compare_event(genb, MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpb, MCPWM_GEN_ACTION_LOW))); } static void dead_time_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb) { mcpwm_dead_time_config_t dead_time_config = { .posedge_delay_ticks = 0, .negedge_delay_ticks = 0, }; // generator_a bypass the deadtime module (no delay) ESP_ERROR_CHECK(mcpwm_generator_set_dead_time(gena, gena, &dead_time_config)); // apply dead time to generator_b dead_time_config.negedge_delay_ticks = 50; ESP_ERROR_CHECK(mcpwm_generator_set_dead_time(genb, genb, &dead_time_config)); } PWMB 上升下降沿延迟,绕过 PWMA 死区 static void gen_action_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb, mcpwm_cmpr_handle_t cmpa, mcpwm_cmpr_handle_t cmpb) { ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(gena, MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH))); ESP_ERROR_CHECK(mcpwm_generator_set_action_on_compare_event(gena, MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpa, MCPWM_GEN_ACTION_LOW))); ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(genb, MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH))); ESP_ERROR_CHECK(mcpwm_generator_set_action_on_compare_event(genb, MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpb, MCPWM_GEN_ACTION_LOW))); } static void dead_time_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb) { mcpwm_dead_time_config_t dead_time_config = { .posedge_delay_ticks = 0, .negedge_delay_ticks = 0, }; // generator_a bypass the deadtime module (no delay) ESP_ERROR_CHECK(mcpwm_generator_set_dead_time(gena, gena, &dead_time_config)); // apply dead time on both edge for generator_b dead_time_config.negedge_delay_ticks = 50; dead_time_config.posedge_delay_ticks = 50; ESP_ERROR_CHECK(mcpwm_generator_set_dead_time(genb, genb, &dead_time_config)); } 载波调制

MCPWM 操作器具有载波子模块,可以根据需要(例如隔离式数字电源应用中)使用变压器传递 PWM 输出信号,实现电机驱动器的电气隔离。在电机需要在全负荷下稳定运行时,各个 PWM 输出信号都将占空比稳定保持在 100% 左右。由于变压器无法直接耦合非交替信号,需要使用载波子模块调制信号,生成交流电波形,从而实现耦合。

调用 mcpwm_operator_apply_carrier(),并提供配置结构体 mcpwm_carrier_config_t,配置载波子模块:

mcpwm_carrier_config_t::frequency_hz 表示载波频率,单位为赫兹。

mcpwm_carrier_config_t::duty_cycle 表示载波的占空比。需注意,支持的占空比选项并不连续,驱动程序将根据配置查找最接近的占空比。

mcpwm_carrier_config_t::first_pulse_duration_us 表示第一个脉冲的脉宽,单位为微秒。该脉冲的分辨率由 mcpwm_carrier_config_t::frequency_hz 中的配置决定。第一个脉冲的脉宽不能为零,且至少为一个载波周期。脉宽越长,电感传导越快。

mcpwm_carrier_config_t::invert_before_modulate 和 mcpwm_carrier_config_t::invert_after_modulate 设置是否在调制前和调制后取反载波输出。

具体而言,可调用 mcpwm_operator_apply_carrier() 并将其配置为 NULL,禁用载波子模块。

故障检测和制动控制

MCPWM 操作器能够感知外部信号,接收有关电机故障、功率驱动器及其他连接设备的信息。这些故障信号封装在 MCPWM 故障对象中。

电机需配置故障模式以及检测到特定故障时的对应操作,例如拉低有刷电机的所有输出,或是锁定步进电机的电流状态等。此操作应使电机重回安全状态,降低故障导致损坏的可能性。

设置故障时操作器的制动模式

MCPWM 操作器对故障的响应方式为 制动。可以调用 mcpwm_operator_set_brake_on_fault(),为每个故障对象配置不同的制动模式。制动的相关配置包含在结构体 mcpwm_brake_config_t 中:

mcpwm_brake_config_t::fault 设置操作器响应的故障类型。

mcpwm_brake_config_t::brake_mode 设置对应故障的制动模式,可以调用 mcpwm_operator_brake_mode_t 查看支持的制动模式。在 MCPWM_OPER_BRAKE_MODE_CBC 模式下,操作器将在故障消失后自行恢复正常,可以通过 mcpwm_brake_config_t::cbc_recover_on_tez 和 mcpwm_brake_config_t::cbc_recover_on_tep 配置恢复时间。在 MCPWM_OPER_BRAKE_MODE_OST 模式下,即使故障消失,操作器也无法恢复正常。此时,需要调用 mcpwm_operator_recover_from_fault(),手动恢复操作器。

设置发生制动事件时的生成器操作

调用 mcpwm_generator_set_actions_on_brake_event() 并辅以若干操作配置,可以针对不同的制动事件,为生成器设置不同的对应操作。操作配置定义在 mcpwm_gen_brake_event_action_t 中:

mcpwm_gen_brake_event_action_t::direction 指定定时器的方向,可以调用 mcpwm_timer_direction_t 查看支持的方向。

mcpwm_gen_brake_event_action_t::brake_mode 指定制动模式,可以调用 mcpwm_operator_brake_mode_t 查看支持的制动模式。

mcpwm_gen_brake_event_action_t::action 指定生成器操作,可以调用 mcpwm_generator_action_t 查看支持的操作。

可借助辅助宏 MCPWM_GEN_BRAKE_EVENT_ACTION 构建制动事件操作条目。

需注意, mcpwm_generator_set_actions_on_brake_event() 的参数列表 必须 以 MCPWM_GEN_BRAKE_EVENT_ACTION_END 结束。

也可以调用 mcpwm_generator_set_action_on_brake_event() 逐一设置制动操作,无需涉及变量参数。

注册故障事件回调

MCPWM 故障检测器支持在检测到实际故障或故障信号消失时发送通知。若有函数需在特定事件发生时调用,则应预先调用 mcpwm_fault_register_event_callbacks(),将所需函数挂载至中断服务程序 (ISR) 中。驱动中故障事件回调函数原型声明为 mcpwm_fault_event_cb_t,其所支持的事件回调类型则列在 mcpwm_fault_event_callbacks_t 中:

mcpwm_fault_event_callbacks_t::on_fault_enter 设置检测到故障时调用的回调函数。

mcpwm_fault_event_callbacks_t::on_fault_exit 设置故障消失后调用的回调函数。

由于上述回调函数在 ISR 中调用,因此,这些函数 不应 涉及 block 操作。可以检查调用 API 的后缀,确保在函数中只调用了后缀为 ISR 的 FreeRTOS API。

函数 mcpwm_fault_register_event_callbacks() 中的 user_data 参数用于保存用户上下文,将直接传递至各个回调函数。

此函数会延迟安装 MCPWM 故障的中断服务。中断服务只能通过 mcpwm_del_fault 移除。

寄存器制动事件回调

MCPWM 操作器支持在进行制动操作前发送通知。若有函数需在特定事件发生时调用,则应预先调用 mcpwm_operator_register_event_callbacks(),将所需函数挂载至中断服务程序 (ISR) 中。驱动中制动事件回调函数原型声明为 mcpwm_brake_event_cb_t,其所支持的事件回调类型则列在 mcpwm_operator_event_callbacks_t 中:

mcpwm_operator_event_callbacks_t::on_brake_cbc 设置操作器进行 逐周期 (CBC) 操作前调用的回调函数。

mcpwm_operator_event_callbacks_t::on_brake_ost 设置操作器进行 一次性 (OST) 操作前调用的回调函数。

由于上述回调函数在 ISR 中调用,因此,这些函数 不应 涉及 block 操作。可以检查调用 API 的后缀,确保在函数中只调用了后缀为 ISR 的 FreeRTOS API。

函数 mcpwm_operator_register_event_callbacks() 中的 user_data 参数用于保存用户上下文,将直接传递至各个回调函数。

此函数会延迟安装 MCPWM 故障的中断服务。中断服务只能通过 mcpwm_del_operator 移除。

生成器强制操作

调用 mcpwm_generator_set_force_level(),使能软件强制决定运行时的生成器输出电平。相较于通过 mcpwm_generator_set_actions_on_timer_event() 配置的其他事件操作,软件强制事件优先级最高。

设置 level 为 -1,代表禁用强制操作,生成器的输出电平重新交由事件操作控制。

设置 hold_on 为 true,代表强制输出电平将保持不变,直到设置 level 为 -1 来移除该电平。

设置 hole_on 为 false,代表强制输出电平仅在短时间有效,随后发生的任何事件都可以改变该电平。

同步模块

MCPWM 定时器接收到同步信号后,定时器将强制进入一个预定义的 相位,该相位由计数值和计数方向共同决定。调用 mcpwm_timer_set_phase_on_sync(),设置同步相位。同步相位配置定义在 mcpwm_timer_sync_phase_config_t 结构体中:

mcpwm_timer_sync_phase_config_t::sync_src 设置同步信号源。创建同步源对象的相关操作,请参见 MCPWM 同步源。具体来说,当此参数设置为 NULL 时,驱动器将禁用 MCPWM 定时器的同步功能。

mcpwm_timer_sync_phase_config_t::count_value 设置接收同步信号后加载至计数器的值。

mcpwm_timer_sync_phase_config_t::direction 设置接收同步信号后的计数方向。

同理, MCPWM 捕获定时器和通道 也支持同步。调用 mcpwm_capture_timer_set_phase_on_sync(),设置捕获定时器的同步相位。同步相位配置定义在 mcpwm_capture_timer_sync_phase_config_t 结构体中:

mcpwm_capture_timer_sync_phase_config_t::sync_src 设置同步信号源。关于如何创建一个同步源对象,请参见 MCPWM 同步源。具体来说,当此参数设置为 NULL 时,驱动器将禁用 MCPWM 捕获定时器的同步功能。

mcpwm_capture_timer_sync_phase_config_t::count_value 设置接收同步信号后加载至计数器的值。

mcpwm_capture_timer_sync_phase_config_t::direction 设置接收同步信号后的计数方向。需注意,不同于 MCPWM 定时器,捕获定时器只支持 MCPWM_TIMER_DIRECTION_UP 这一个计数方向。

使用 GPIO 同步定时器

GPIO Sync All MCPWM Timers

static void example_setup_sync_strategy(mcpwm_timer_handle_t timers[]) { mcpwm_sync_handle_t gpio_sync_source = NULL; mcpwm_gpio_sync_src_config_t gpio_sync_config = { .group_id = 0, // GPIO 故障应与以上定时器位于同一组中 .gpio_num = EXAMPLE_SYNC_GPIO, .flags.pull_down = true, .flags.active_neg = false, // 默认情况下,一个上升沿脉冲可以触发一个同步事件 }; ESP_ERROR_CHECK(mcpwm_new_gpio_sync_src(&gpio_sync_config, &gpio_sync_source)); mcpwm_timer_sync_phase_config_t sync_phase_config = { .count_value = 0, // 同步相位:目标计数值 .direction = MCPWM_TIMER_DIRECTION_UP, // 同步相位:计数方向 .sync_src = gpio_sync_source, // 同步源 }; for (int i = 0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3